package com.googlecode.connectlet.crypto.cipher.mode;

import com.googlecode.connectlet.util.Bytes;

public abstract class EcbCipher implements FinalBlock {
	public abstract int update(byte[] input, int inputOffset, int inputLen,
			byte[] output, int outputOffset);

	protected byte[] block;
	protected int blockSize, blockOffset = 0;

	private static final int BUFFER_SIZE = 2048;

	public void init() {
		blockOffset = 0;
	}

	public int getOutputSize(int inputLen) {
		return (inputLen + blockSize + BUFFER_SIZE) / BUFFER_SIZE * BUFFER_SIZE;
	}

	private byte[] buffer = null;

	private void setBuffer(int inputLen) {
		int bufferSize = getOutputSize(inputLen);
		if (buffer == null || buffer.length < bufferSize) {
			buffer = new byte[bufferSize];
		}
	}

	public byte[] doFinal(byte[] input, int inputOffset, int inputLen) {
		setBuffer(inputLen);
		if (input == null) {
			return Bytes.left(buffer, doFinal(buffer, 0));
		}
		int outputLen = update(input, inputOffset, inputLen, buffer, 0);
		outputLen += doFinal(buffer, outputLen);
		return Bytes.left(buffer, outputLen);
	}

	public byte[] doFinal(byte[] input) {
		return doFinal(input, 0, input.length);
	}
}